package com.yjc.drygoods.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yjc.common.to.SkuInfoTo;
import com.yjc.common.to.SkuReductionTo;
import com.yjc.common.utils.R;
import com.yjc.drygoods.cart.feign.CouponFeignService;
import com.yjc.drygoods.cart.feign.ProductFeignService;
import com.yjc.drygoods.cart.interceptor.CartInterceptor;
import com.yjc.drygoods.cart.service.CartService;
import com.yjc.drygoods.cart.to.SkuFullReductionTo;
import com.yjc.drygoods.cart.to.SkuLadderTo;
import com.yjc.drygoods.cart.to.UserInfoTo;
import com.yjc.drygoods.cart.vo.Cart;
import com.yjc.drygoods.cart.vo.CartItem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author yjc
 * @create 2022-09-21 20:10
 */
@Service
@Slf4j
public class CartServiceImpl implements CartService {

    private final String CART_PREFIX = "drygoods:cart:";

    @Autowired
    ProductFeignService productFeignService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    ThreadPoolExecutor threadPool;

    @Autowired
    CouponFeignService couponFeignService;

    @Override
    public CartItem addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        String cartJson = (String) cartOps.get(skuId.toString());

        if (StringUtils.isEmpty(cartJson)) {
            CartItem cartItem = new CartItem();
            //缓存中没有该购物项
            CompletableFuture<Void> skuBaseInfoFuture = CompletableFuture.runAsync(() -> {
                //设置购物项的一些基本属性
                R r = productFeignService.info(skuId);
                SkuInfoTo skuInfo = r.getData("skuInfo", new TypeReference<SkuInfoTo>() {
                });
                cartItem.setCheck(true);
                cartItem.setCount(num);
                cartItem.setImage(skuInfo.getSkuDefaultImg());
                cartItem.setPrice((skuInfo.getReducedPrice().compareTo(new BigDecimal("0.0000"))==0)?skuInfo.getPrice():skuInfo.getReducedPrice());
                cartItem.setSkuId(skuId);
                cartItem.setSpuId(skuInfo.getSpuId());
                cartItem.setTitle(skuInfo.getSkuTitle());
                cartItem.setWeight(skuInfo.getWeight());
                //设置购物项的满减优惠和打折优惠
                SkuReductionTo skuReductionTo = new SkuReductionTo();
                skuReductionTo.setSkuId(skuId);
                R rSkuFullInfo = couponFeignService.getSkuFullReductionInfoByskuId(skuId);
                if (rSkuFullInfo.getCode() == 0) {
                    SkuFullReductionTo data = rSkuFullInfo.getData(new TypeReference<SkuFullReductionTo>() {
                    });
                    if (data != null) {
                        skuReductionTo.setFullPrice(data.getFullPrice());
                        skuReductionTo.setReducePrice(data.getReducePrice());
                    }
                }
                R rSkuLadderInfo = couponFeignService.getSkuLadderInfoByskuId(skuId);
                if (rSkuLadderInfo.getCode() == 0) {
                    SkuLadderTo data = rSkuLadderInfo.getData(new TypeReference<SkuLadderTo>() {
                    });
                    if (data != null) {
                        skuReductionTo.setFullCount(data.getFullCount());
                        skuReductionTo.setDiscount(data.getDiscount());
                    }
                }
                cartItem.setSkuReduction(skuReductionTo);

            }, threadPool);
            CompletableFuture<Void> skuSaleAttrFuture = CompletableFuture.runAsync(() -> {
                //设置购物项的销售属性(套餐属性)
                R r2 = productFeignService.getSkuSaleAttrs(skuId);
                List<String> data = (List<String>) r2.get("data");
                cartItem.setSkuAttr(data);
            }, threadPool);
            CompletableFuture.allOf(skuBaseInfoFuture, skuSaleAttrFuture).get();
            String s = JSON.toJSONString(cartItem);
            cartOps.put(skuId.toString(), s);
            return cartItem;
        }
        CartItem cartItem1 = JSON.parseObject(cartJson, CartItem.class);
        cartItem1.setCount(cartItem1.getCount() + num);
        String s = JSON.toJSONString(cartItem1);
        cartOps.put(skuId.toString(), s);
        return cartItem1;


    }

    @Override
    public CartItem getCartItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String s = (String) cartOps.get(skuId.toString());
        CartItem cartItem = JSON.parseObject(s, CartItem.class);
        return cartItem;
    }

    @Override
    public Cart getCart() throws ExecutionException, InterruptedException {
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        Cart cart = new Cart();
        String cartKey = "";
        if (userInfoTo.getUserId() != null) {
            //用户已登录
            cartKey = CART_PREFIX + userInfoTo.getUserId();

            List<CartItem> cartItemsUserKey = getCartItems(CART_PREFIX + userInfoTo.getUserKey());
            if (cartItemsUserKey != null && cartItemsUserKey.size() > 0) {
                for (CartItem cartItem : cartItemsUserKey) {
                    //合并购物车时会去数据库获取最新的sku干货信息
                    addToCart(cartItem.getSkuId(), cartItem.getCount());
                }
                clearCartItems(CART_PREFIX + userInfoTo.getUserKey());
            }
            List<CartItem> cartItems = getCartItems(cartKey);
            cart.setItems(cartItems);
        } else {
            cartKey = CART_PREFIX + userInfoTo.getUserKey();
            List<CartItem> res = getCartItems(cartKey);
            cart.setItems(res);
        }
        return cart;
    }

    public void clearCartItems(String cartKey) {
        stringRedisTemplate.delete(cartKey);
    }


    public List<CartItem> getCartItems(String cartKey) {
        BoundHashOperations<String, Object, Object> cartops = stringRedisTemplate.boundHashOps(cartKey);
        List<Object> values = cartops.values();
        if (values != null && values.size() > 0) {
            List<CartItem> res = values.stream().map(item -> {
                CartItem cartItem = JSON.parseObject((String) item, CartItem.class);
                return cartItem;
            }).collect(Collectors.toList());
            return res;
        }
        return null;
    }

    public BoundHashOperations<String, Object, Object> getCartOps() {
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        String cartKey = "";
        if (userInfoTo.getUserId() != null) {
            //用户已登录
            cartKey = CART_PREFIX + userInfoTo.getUserId();
        } else {
            cartKey = CART_PREFIX + userInfoTo.getUserKey();
        }
        BoundHashOperations<String, Object, Object> cartHashOps = stringRedisTemplate.boundHashOps(cartKey);
        return cartHashOps;
    }

    @Override
    public void setCartItemCheckStatus(Long skuId, Integer check) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String s = (String) cartOps.get(skuId.toString());
        CartItem cartItem = JSON.parseObject(s, CartItem.class);
        cartItem.setCheck(check == 1 ? true : false);
        String s1 = JSON.toJSONString(cartItem);
        cartOps.put(skuId.toString(), s1);
    }

    @Override
    public void setCartItemCount(Long skuId, Integer num) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        CartItem cartItem = getCartItem(skuId);
        cartItem.setCount(num);
        cartOps.put(skuId.toString(), JSON.toJSONString(cartItem));
    }

    /**
     * 单个删除
     *
     * @param deleteId
     */
    @Override
    public void deleteCartItem(Long deleteId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        cartOps.delete(deleteId.toString());
    }


    public void deleteAllCartItem() {
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        String cartKey = "";
        if (userInfoTo.getUserId() != null) {
            //用户已登录
            cartKey = CART_PREFIX + userInfoTo.getUserId();
        } else {
            cartKey = CART_PREFIX + userInfoTo.getUserKey();
        }
        Boolean delete = stringRedisTemplate.delete(cartKey);
    }

    @Override
    public List<CartItem> getCurrentUserAllCartItems() {

        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        if (userInfoTo.getUserId() == null) {
            return null;
        } else {
            String cartKey = CART_PREFIX + userInfoTo.getUserId();
            List<CartItem> cartItems = getCartItems(cartKey);
            if (cartItems != null && cartItems.size() > 0) {
                List<CartItem> cartItemList = cartItems.stream()
                        .filter(item -> item.getCheck())
                        .map(item -> {
                            //调用远程商品服务，获取该商品最新价格
                            Long skuId = item.getSkuId();
                            R info = productFeignService.info(skuId);
                            SkuInfoTo skuInfo = info.getData("skuInfo", new TypeReference<SkuInfoTo>() {
                            });
                            item.setPrice(skuInfo.getPrice());
                            return item;
                        }).collect(Collectors.toList());
                return cartItemList;
            }
        }
        return null;
    }
}
